#import "Injective.h"
#import "InjectiveContextXMLFactory.h"


@implementation Injective
static Injective *context = NULL;
@synthesize container = _container;
@synthesize context;

InjectiveProperty(context)



#pragma mark -
#pragma mark init and deallog

- (void)dealloc
{
	[_container release];
	[super dealloc];
}

- (id)init
{
	if (self = [super init]) {
		_container =  [[InjectiveContainer alloc] init];
	}
	return self;
}

#pragma mark -
#pragma mark singleton implementation

+ (Injective *) context
{
	if ( context == NULL) {
		context = [[[Injective alloc] init] retain];
	}
	return context;
}

#pragma mark -
#pragma static methods
+ (id)getObject:(id)component
{
	return [context getObject:component];
}

+ (id)getObjectByID:(NSString *)ID
{
	return [self.context.container getObjectByID:ID];
}

+ (void)wireInstance:(id)instance
{
	[self.context wireInstance:instance];
}

+ (void) clearContext
{
	//Only call this if you know what you're doing!
	[self.context.container clearContext];
}

+ (void) addInstance:(id)instance
{
	[self.context.container addInstance:instance];
}

+ (void) addInstance:(id)instance forType:(id) type
{
	[self.context.container addInstance:instance forType:type];
}

+ (void) initializeAutoInitializeIntances
{
	NSArray *objectDescriptions = [[self.context.container objectDescriptionsInContext] retain];
	for (InjectiveObjectDescription *objectDescription in objectDescriptions) {
		if (objectDescription.isSingleton && objectDescription.autoInitialize && objectDescription.ID != nil) {
			NSLog(@"/n automatically instantiating %@ type of %@",objectDescription.ID, objectDescription.type );
			[self.context.container getObjectByID:objectDescription.ID];
		}
	}
	[objectDescriptions release];
}

#pragma mark -
#pragma mark public interface

- (id)getObject:(id)component
{
	return [self.container getObject:component];
}

- (void)wireInstance:(id)instance
{
	[self.container wireInstance:instance];
}

- (BOOL)loadXMLConfig:(NSString *) fileName
{
	InjectiveContextXMLFactory *xmlFactory = [[InjectiveContextXMLFactory alloc] init];
	NSArray *objectDescriptions = [xmlFactory processXMLFile:fileName];
	[xmlFactory release];
	
	return [self addObjectsToContext:objectDescriptions];
}


- (BOOL)loadXMLConfigWithOverrides:(NSString *) fileName
{
	InjectiveContextXMLFactory *xmlFactory = [[InjectiveContextXMLFactory alloc] init];
	NSArray *objectDescriptions = [xmlFactory processXMLFile:fileName];
	[xmlFactory release];
	
	return [self addObjectsToContext:objectDescriptions overridesIfIdsAreTheSame:YES];
}

- (BOOL) addObjectsToContext: (NSArray *) objects
{
	return [self addObjectsToContext:objects overridesIfIdsAreTheSame:NO];
}

- (BOOL) addObjectsToContext: (NSArray *) objects overridesIfIdsAreTheSame:(BOOL) isOverriden
{
	for (InjectiveObjectDescription *objectDescription in objects) {
		NSLog(@"adding object %@", objectDescription);
		[self.container addObject:objectDescription overrideIfIdsAreEqual:isOverriden];
	}
	return YES;
}

- (NSString *) description
{
	return [[super description] stringByAppendingFormat:@" current context is : %@", self.container];
}

@end